﻿using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TyMES.Model.Record;
using Newtonsoft.Json;
using WalkingTec.Mvvm.Core;
using Microsoft.AspNetCore.SignalR;
using TyMES.MidWare;
using TyMES.PassStationCommunication;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Rebus.Threading;
using Microsoft.IdentityModel.Tokens;
using static TyMES.Communication.Response.UIResponse;
using static TyMES.BaseInformation.Controllers.StationController;
using MediatR;
using TyMES.Communication;

namespace TyMES.Services
{
    public class BadProductService
    {
        
        private readonly WTMContext _context;
        private readonly IHubContext<InverseControlHub> inverseControl;
        private readonly IHubContext<NotificationHub> notification;
        private readonly PassStationService passStationService;
        public BadProductService(WTMContext context, IHubContext<InverseControlHub> inversecontrol, IHubContext<NotificationHub> _notification, PassStationService passstationservice)
        {           
            _context = context;
            inverseControl = inversecontrol;
            passStationService = passstationservice;
            notification = _notification;
        }
        /// <summary>
        /// 增加确认人
        /// </summary>
        /// <param name="datainfo"></param>
        /// <returns></returns>
        public async Task<ResponseComBool> Addpeople(VerifierRecord datainfo)
        {
            try
            {
                if (datainfo == null || datainfo.PersonID.IsNullOrEmpty() || datainfo.PassWord.IsNullOrEmpty())
                {
                    return new ResponseComBool
                    {
                        Success = false,
                        Mesg = $"添加{datainfo.PersonID}失败，工号或密码为空"
                    };
                }
                datainfo.CreateTime = DateTime.Now;//创建时间
                await _context.DC.Set<VerifierRecord>().AddAsync(datainfo);
                _context.DC.SaveChanges();
                return new ResponseComBool
                {
                    Success = true,
                    Mesg = "添加成功"
                };

            }
            catch (Exception ex)
            {
                return new ResponseComBool
                {
                    Success = false,
                    Mesg = $"添加{datainfo.PersonID}失败,{ex.Message}"
                };
            }
        }

        /// <summary>
        ///  确认人登录验证
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public async Task<ResponseComBool> CheckIdAndPassword(VerifierRecord v)
        {
            try
            {
                if(v == null || v.PersonID.IsNullOrEmpty() || v.PassWord.IsNullOrEmpty())
                {
                    return new ResponseComBool
                    {
                        Success = false,
                        Mesg = "工号或密码为空"
                    };
                }
                var res = await _context.DC.Set<VerifierRecord>().Where(x => x.PersonID == v.PersonID && x.PassWord == v.PassWord).FirstOrDefaultAsync();
                if (res != null)
                {
                    return new ResponseComBool
                    {
                        Success = true,
                        Mesg = "验证成功"
                    };
                }
                else
                {
                    return new ResponseComBool
                    {
                        Success = false,
                        Mesg = "工号或密码错误"
                    };
                }
                
            }
            catch(Exception ex)
            {
                return new ResponseComBool
                {
                    Success = false,
                    Mesg = ex.Message
                };               
            }                       
        }

        /// <summary>
        /// 确认不良，添加不良产品记录，NG放行并插入过站记录（增加一个属性记录人工确认 不良品/合格品，后续过站获取到最新出站记录该属性为'不良品'时可自动跳站
        /// </summary>
        /// <param name="badproinfo"></param>
        /// <returns></returns>
        public async Task<ResponseComBool> ConfirmBadproNG(BadProductRecord badproinfo)
        {
            try
            {
                if (badproinfo == null || badproinfo.SnNumber.IsNullOrEmpty())
                {
                    return new ResponseComBool
                    {
                        Success = false,
                        Mesg = "不能为空记录"
                    };
                }
                //添加不良品信息记录
                badproinfo.CreateTime = DateTime.Now;
                await _context.DC.Set<BadProductRecord>().AddAsync(badproinfo);
                _context.DC.SaveChanges();

                //添加过站记录
                await ForcePassStation(badproinfo, "不良品");

                return new ResponseComBool
                {
                    Success = true,
                    Mesg = "不良品信息添加成功"
                };
            }
            catch (Exception ex)
            {
                return new ResponseComBool
                {
                    Success = false,
                    Mesg = ex.Message
                };
            }
        }

        /// <summary>
        /// 确认合格 插入一条过站记录 
        /// </summary>
        /// <param name="badproinfo"></param>
        /// <returns></returns>
        public async Task<ResponseComBool> ConfirmBadproOK(BadProductRecord badproinfo)
        {
            try
            {
                if (badproinfo == null || badproinfo.SnNumber.IsNullOrEmpty())
                {
                    return new ResponseComBool
                    {
                        Success = false,
                        Mesg = "不能为空记录"
                    };
                }
                //添加过站记录
                await ForcePassStation(badproinfo, "合格品");

                return new ResponseComBool
                {
                    Success = true,
                    Mesg = "确认合格过站"
                };
            }
            catch (Exception ex)
            {
                return new ResponseComBool
                {
                    Success = false,
                    Mesg = ex.Message
                };
            }
        }

        //强制出战
        public async Task<TrayBVSNResponse> ForcePassStation(BadProductRecord para, string proType)
        {

            StationLogRecord stationLog = new StationLogRecord();
            stationLog.Date_Time = DateTime.Now;
            stationLog.CreateTime = DateTime.Now;
            stationLog.LineCode = para.LineCode;
            stationLog.StationCode = para.StationCode;
            // 直接插入出站记录
            try
            {
                //目前强制进出站第一步就是要给个强制放的信号
                await inverseControl.Clients.All.SendAsync("ReceiveMessage", new INotice(para.LineCode, para.StationCode, "1"));
                // 查找sn入站信息
                if (para.SnNumber == "" || para.SnNumber == null)
                {
                    stationLog.LogType = "bad";
                    stationLog.Log = "强制进站sn为空，无法记录出站信息";
                    await DoAddStationStatusLog(stationLog);
                    return new TrayBVSNResponse("000002", false, true, para.SnNumber, "强制进站sn为空，无法记录出站信息", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                }
                else
                {
                    //查找进站记录
                    var inStationInfo = await passStationService.FindInStationInfoAsync(para.SnNumber, para.LineCode, para.StationCode);
                    if (inStationInfo == null)
                    {
                        stationLog.LogType = "bad";
                        stationLog.Log = $"强制出站，sn{para.SnNumber}无进站信息";
                        await DoAddStationStatusLog(stationLog);
                        return new TrayBVSNResponse("000003", false, true, para.SnNumber, $"强制出站，sn{para.SnNumber}无进站信息", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    }
                    PassStationRecord outStationInfo = new PassStationRecord()
                    {
                        LineCode = inStationInfo.LineCode,
                        MaterialCode = inStationInfo.MaterialCode,
                        MaterialName = inStationInfo.MaterialName,
                        MaterialVersion = inStationInfo.MaterialVersion,
                        OperationCode = inStationInfo.OperationCode,
                        OrderCode = inStationInfo.OrderCode,
                        ScheduleCode = inStationInfo.ScheduleCode,
                        SnNumber = inStationInfo.SnNumber,
                        StationCode = inStationInfo.StationCode,
                        PassEndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        PassStatus = "pass",
                        ReqType = "2",
                        CreateTime = DateTime.Now,
                        Uploadflag = false,
                        Manual_Check = proType
                    };

                    PassStationRequestSup passStationRequestSup = new PassStationRequestSup()
                    {
                        operationCode = inStationInfo.OperationCode,
                        lineCode = inStationInfo.LineCode,
                        stationCode = inStationInfo.StationCode,
                        snNumber = inStationInfo.SnNumber,
                        orderCode = inStationInfo.OrderCode,
                        scheduleCode = inStationInfo.ScheduleCode,

                    };
                    await passStationService.BatchBindSN(passStationRequestSup);
                    await ChangeBindOrder(passStationRequestSup);
                    _context.DC.Set<PassStationRecord>().Add(outStationInfo);
                    //完成控制PLC操作

                    await _context.DC.SaveChangesAsync();
                }


            }
            catch (Exception ex)
            {
                stationLog.LogType = "bad";
                stationLog.Log = para.SnNumber + "出站异常";
                await DoAddStationStatusLog(stationLog);
                return new TrayBVSNResponse("000001", false, true, para.SnNumber, "出站异常", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            }
            stationLog.LogType = "good";
            stationLog.Log = $"SN:{para.SnNumber}强制出站成功";
            await DoAddStationStatusLog(stationLog);
            return new TrayBVSNResponse("000000", true, false, para.SnNumber, $"SN:{para.SnNumber}强制出站成功", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
        }

        public async Task<bool> DoAddStationStatusLog(StationLogRecord stationLog)
        {
            stationLog.Date_Time = DateTime.Now;
            stationLog.CreateTime = DateTime.Now;
            _context.DC.Set<StationLogRecord>().Add(stationLog);
            _context.DC.SaveChanges();
            await notification.Clients.All.SendAsync("ReceiveMessage", new Notice(stationLog.LineCode, stationLog.StationCode));
            return true;
        }


        /// <summary>换绑
        /// 2-OP4010测试线上线工序需要进行工单换绑，查询到电机装配上线的工单绑定信息，完成换绑
        /// </summary>
        /// <param name="passStationRequestSup"></param>
        /// <returns></returns>
        public async Task<ResponseBase> ChangeBindOrder(PassStationRequestSup passStationRequestSup)
        {
            try
            {
                if (passStationRequestSup.operationCode == "2-OP4010" && passStationRequestSup.snNumber.Substring(0, 7) != "DM-TG-Y")
                {
                    //测试线上线工序非标准件执行换绑
                    var TZSnnumber = _context.DC.Set<MaterialBindRecord>().Where(x => x.StationCode == passStationRequestSup.stationCode && x.SnNumber == passStationRequestSup.snNumber).FirstOrDefault()?.AssemblyMaterialSn;
                    if (TZSnnumber == null)
                    {
                        await passStationService.stationlogadd3(passStationRequestSup.lineCode, passStationRequestSup.stationCode, passStationRequestSup.snNumber, "bad", $"SN:{passStationRequestSup.snNumber}未查询到其在测试线首工位的物料绑定记录");
                        return new ResponseBase(false, $"SN:{passStationRequestSup.snNumber}换绑失败,未查询到其在测试线首工位的物料绑定记录");
                    }
                    var TZtraybindvsnrecord = _context.DC.Set<TrayBindVSN>().Where(x => x.VSN == TZSnnumber).AsNoTracking().FirstOrDefault();
                    var currenttraybindvsnrecord = _context.DC.Set<TrayBindVSN>().Where(x => x.VSN == passStationRequestSup.snNumber).FirstOrDefault();

                    if (TZtraybindvsnrecord == null)
                    {
                        return new ResponseBase(false, $"未查询到电机SN:{TZSnnumber}的托盘SN绑定记录");
                    }
                    else
                    {
                        currenttraybindvsnrecord.OrderCode = TZtraybindvsnrecord.OrderCode;
                        currenttraybindvsnrecord.ScheduleCode = TZtraybindvsnrecord.ScheduleCode;
                        _context.DC.SaveChanges();
                        return new ResponseBase(true, $"SN:{passStationRequestSup.snNumber}改绑成功");
                    }


                }
                return new ResponseBase(true, $"SN:{passStationRequestSup.snNumber}无需改绑");
            }
            catch (Exception ex)
            {
                return new ResponseBase(false, $"SN:{passStationRequestSup.snNumber}换绑失败:{ex.Message}");
            }
        }

    }



}
